﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Threading;

namespace FotoButh
{
    class ButtonNotifier : IDisposable
    {
        public event EventHandler ButtonPushed;
        public event EventHandler ComFound;
        public event EventHandler ComLost;
        private SerialPort _serialPort = null;
        private bool _buttonPressed = false;
        private string _comPort = string.Empty;
        private DateTime _lastButtonPush = DateTime.Now;

        public ButtonNotifier()
        { }

        public string ComPort
        {
            get
            {
                return _comPort;
            }
            set
            {
                OpenSerialPort(value);
            }
        }

        // Only fire ButtonPushed when the button is pressed (OnPress)
        private void PinChanged(object sender, SerialPinChangedEventArgs e)
        {
            _buttonPressed = !_buttonPressed;
            if (_buttonPressed && DateTime.Now > _lastButtonPush.AddSeconds(10))
            {
                FireButtonPushed();
                _lastButtonPush = DateTime.Now;
            }
        }

        private void FireButtonPushed()
        {
            if (ButtonPushed != null)
                ButtonPushed(this, null);
        }

        private void FireCom(bool found)
        {
            if (found)
            {
                if (ComFound != null)
                    ComFound(this, EventArgs.Empty);
            }
            else
            {
                if (ComLost != null)
                    ComLost(this, EventArgs.Empty);
            }
        }

        private void OpenSerialPort(string port)
        {
            if (!string.IsNullOrEmpty(port))
            {
                try
                {
                    CloseSerialPort();
                    _serialPort = new SerialPort(port);
                    _serialPort.Open();
                    _serialPort.DtrEnable = true;
                    _serialPort.PinChanged += new SerialPinChangedEventHandler(PinChanged);
                    _comPort = port;
                    FireCom(true);
                }
                catch (Exception e)
                {
                    CloseSerialPort();
                    FireCom(false);
                }
            }
        }

        private void CloseSerialPort()
        {
            if (_serialPort != null)
            {
                try
                {
                    _serialPort.PinChanged -= new SerialPinChangedEventHandler(PinChanged);
                    _serialPort.Close();
                    _serialPort = null;
                }
                catch (Exception)
                { }
            }
        }

        #region IDisposable Members
        public void  Dispose()
        {
            CloseSerialPort();
        }
        #endregion
    }
}
